package com.qingcloud.adminbackend.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.f4b6a3.ulid.UlidCreator;
import com.google.common.collect.ImmutableMap;
import com.qingcloud.adminbackend.entity.app.*;
import com.qingcloud.adminbackend.entity.sysfunction.SysFunction;
import com.qingcloud.adminbackend.entity.sysorder.SysBusinessApp;
import com.qingcloud.adminbackend.entity.sysorg.SysUserOrg;
import com.qingcloud.adminbackend.entity.user.SimpleUserDTO;
import com.qingcloud.adminbackend.entity.user.SysUser;
import com.qingcloud.adminbackend.entity.usergroup.SysUsergroup;
import com.qingcloud.adminbackend.entity.usergroup.SysUsergroupUser;
import com.qingcloud.adminbackend.enums.DataSourceEnum;
import com.qingcloud.adminbackend.enums.UcRoleEnum;
import com.qingcloud.adminbackend.mapper.*;
import com.qingcloud.adminbackend.mapper.app.*;
import com.qingcloud.adminbackend.pojo.app.*;
import com.qingcloud.adminbackend.service.IAppService;
import com.qingcloud.base.constant.DateFormatterConstant;
import com.qingcloud.base.exception.WamingException;
import com.qingcloud.base.remote.pojo.AppFunctionParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipFile;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wangjinnan
 * @since 2021-03-17
 */
@Slf4j
@Service
public class AppServiceImpl extends ServiceImpl<WebPubAppMapper, WebPubApp> implements IAppService {

    @Resource
    private WebPubAppMapper appMapper;

    @Resource
    private WebPubPageMapper pageMapper;

    @Resource
    private WebPubPageResourceMapper resourceMapper;

    @Resource
    private WebPubPageVariableMapper variableMapper;

    @Resource
    private StaticResourceMapper staticResourceMapper;

    @Resource
    private ApiBaseMapper apiBaseMapper;

    @Resource
    private ApiDocMapper apiDocMapper;

    @Resource
    private ApiParameterMapper apiParameterMapper;

    @Resource
    private ApiResponseMapper apiResponseMapper;

    @Resource
    private AppDataSourceMapper appDataSourceMapper;

    @Resource
    private JobMapper jobMapper;

    @Resource
    private JobComponentInstanceMapper instanceMapper;

    @Resource
    private JobComponentInstanceParameterMapper parameterMapper;

    @Resource
    private JobComponentInstanceOutputMapper outputMapper;

    @Resource
    private JobComponentInstanceOutMappingMapper outMappingMapper;

    @Resource
    private JobComponentInstanceRelationMapper relationMapper;

    @Resource
    private JobComponentInstanceSchedulerMapper schedulerMapper;

    @Resource
    private SysBusinessAppMapper businessAppMapper;

    @Resource
    private SysFunctionMapper sysFunctionMapper;

    @Resource
    private UserAppRoleMapper userAppRoleMapper;

    @Resource
    private SysUserOrgMapper sysUserOrgMapper;

    @Resource
    private SysUsergroupMapper sysUsergroupMapper;

    @Resource
    private SysUsergroupUserMapper usergroupUserMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private AppShareMapper appShareMapper;

    /**
     * 导入应用
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void importApp(ZipFile zipFile) {
        String tmpDir = System.getProperty("java.io.tmpdir");
        String rootDir = tmpDir + File.separator + "webapp" + IdUtil.getSnowflakeNextIdStr();
        ZipUtil.unzip(zipFile, new File(rootDir));
        for (File dir : FileUtil.ls(rootDir)) {
            //前端应用信息
            String appConfigFile = rootDir + File.separator + dir.getName() + File.separator + "app.json";
            if (FileUtil.exist(appConfigFile)) {
                WebAppExportDTO webAppExportDTO = JSONObject.parseObject(FileUtil.readUtf8String(appConfigFile), WebAppExportDTO.class);
                if (webAppExportDTO != null) {
                    appMapper.delete(Wrappers.<WebPubApp>lambdaQuery().eq(WebPubApp::getDevAppId, webAppExportDTO.getWebPubApp().getDevAppId()));
                    jobMapper.delete(Wrappers.<Job>lambdaQuery().eq(Job::getAppId, webAppExportDTO.getWebPubApp().getDevAppId()));

                    Long total = appMapper.selectCount(new QueryWrapper<>());
                    if (total >= 5) {
                        throw new WamingException("导入应用超限，请联系客服");
                    }

                    webAppExportDTO.getWebPubApp().setImportTime(LocalDateTime.now().format(DateFormatterConstant.NORMAL_FULL_FORMATTER));
                    appMapper.insert(webAppExportDTO.getWebPubApp());

                    pageMapper.delete(Wrappers.<WebPubPage>lambdaQuery().eq(WebPubPage::getAppId, webAppExportDTO.getWebPubApp().getId()));
                    resourceMapper.delete(Wrappers.<WebPubPageResource>lambdaQuery().eq(WebPubPageResource::getAppId, webAppExportDTO.getWebPubApp().getId()));
                    variableMapper.delete(Wrappers.<WebPubPageVariable>lambdaQuery().eq(WebPubPageVariable::getAppId, webAppExportDTO.getWebPubApp().getId()));
                    staticResourceMapper.delete(Wrappers.<StaticResource>lambdaQuery().eq(StaticResource::getAppId, webAppExportDTO.getWebPubApp().getId()));

                    if (CollUtil.isNotEmpty(webAppExportDTO.getPages())) {
                        for (WebPubPage it : webAppExportDTO.getPages()) {
                            pageMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(webAppExportDTO.getResources())) {
                        for (WebPubPageResource it : webAppExportDTO.getResources()) {
                            resourceMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(webAppExportDTO.getVariables())) {
                        for (WebPubPageVariable it : webAppExportDTO.getVariables()) {
                            variableMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(webAppExportDTO.getStaticResources())) {
                        for (StaticResource it : webAppExportDTO.getStaticResources()) {
                            staticResourceMapper.insert(it);
                        }
                    }
                    //业务种类
                    int menuType = Integer.parseInt(webAppExportDTO.getMenuType());
                    SysBusinessApp sysBusinessApp = businessAppMapper.selectById(menuType);
                    if (sysBusinessApp == null) {
                        sysBusinessApp = new SysBusinessApp();
                        sysBusinessApp.setId(menuType);
                        sysBusinessApp.setName(webAppExportDTO.getWebPubApp().getName());
                        sysBusinessApp.setType(1);
                        sysBusinessApp.setOrigin(2);
                        sysBusinessApp.setBizCode(String.valueOf(webAppExportDTO.getWebPubApp().getDevAppId()));
                        businessAppMapper.saveImportApp(sysBusinessApp);
                    }
                    int orgAppNum = businessAppMapper.countOrgApp(menuType);
                    if (orgAppNum <= 0) {
                        businessAppMapper.saveOrgApp("SUPER-ORG", menuType);
                    }
                    //权限
                    sysFunctionMapper.delete(Wrappers.<SysFunction>lambdaQuery().eq(SysFunction::getMenuType, menuType));
                    if (CollUtil.isNotEmpty(webAppExportDTO.getFunctions())) {
                        for (SysFunction function : webAppExportDTO.getFunctions()) {
                            sysFunctionMapper.insert(function);
                        }
                    }
                }
            }

            //API信息
            String apiFile = rootDir + File.separator + dir.getName() + File.separator + "api.json";
            if (FileUtil.exist(apiFile)) {
                ApiExportDTO apiExportDTO = JSONObject.parseObject(FileUtil.readUtf8String(apiFile), ApiExportDTO.class);
                if (apiExportDTO != null) {
                    if (CollUtil.isNotEmpty(apiExportDTO.getApiBases())) {
                        for (ApiBase it : apiExportDTO.getApiBases()) {
                            apiBaseMapper.deleteById(it.getId());
                            apiDocMapper.delete(Wrappers.<ApiDoc>lambdaQuery().eq(ApiDoc::getApiId, it.getId()));
                            apiParameterMapper.delete(Wrappers.<ApiParameter>lambdaQuery().eq(ApiParameter::getApiId, it.getId()));
                            apiResponseMapper.delete(Wrappers.<ApiResponse>lambdaQuery().eq(ApiResponse::getApiId, it.getId()));
                            apiBaseMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(apiExportDTO.getApiDocs())) {
                        for (ApiDoc it : apiExportDTO.getApiDocs()) {
                            apiDocMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(apiExportDTO.getParameters())) {
                        for (ApiParameter it : apiExportDTO.getParameters()) {
                            apiParameterMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(apiExportDTO.getResponses())) {
                        for (ApiResponse it : apiExportDTO.getResponses()) {
                            apiResponseMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(apiExportDTO.getAppDataSources())) {
                        for (AppDataSource it : apiExportDTO.getAppDataSources()) {
                            appDataSourceMapper.deleteById(it.getId());
                            appDataSourceMapper.insert(it);
                        }
                    }
                }
            }

            //作业信息
            String jobFile = rootDir + File.separator + dir.getName() + File.separator + "job.json";
            if (FileUtil.exist(jobFile)) {
                JobExportDTO jobExportDTO = JSONObject.parseObject(FileUtil.readUtf8String(jobFile), JobExportDTO.class);
                if (jobExportDTO != null) {
                    if (CollUtil.isNotEmpty(jobExportDTO.getJobs())) {
                        for (Job it : jobExportDTO.getJobs()) {
                            jobMapper.deleteById(it.getId());
                            instanceMapper.delete(Wrappers.<JobComponentInstance>lambdaQuery().eq(JobComponentInstance::getJobId, it.getId()));
                            relationMapper.delete(Wrappers.<JobComponentInstanceRelation>lambdaQuery().eq(JobComponentInstanceRelation::getJobId, it.getId()));
                            jobMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getInstances())) {
                        for (JobComponentInstance it : jobExportDTO.getInstances()) {
                            parameterMapper.delete(Wrappers.<JobComponentInstanceParameter>lambdaQuery().eq(JobComponentInstanceParameter::getInstanceId, it.getId()));
                            outputMapper.delete(Wrappers.<JobComponentInstanceOutput>lambdaQuery().eq(JobComponentInstanceOutput::getInstanceId, it.getId()));
                            outMappingMapper.delete(Wrappers.<JobComponentInstanceOutMapping>lambdaQuery().eq(JobComponentInstanceOutMapping::getInstanceId, it.getId()));
                            schedulerMapper.delete(Wrappers.<JobComponentInstanceScheduler>lambdaQuery().eq(JobComponentInstanceScheduler::getInstanceId, it.getId()));
                            instanceMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getParameters())) {
                        for (JobComponentInstanceParameter it : jobExportDTO.getParameters()) {
                            parameterMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getOutputs())) {
                        for (JobComponentInstanceOutput it : jobExportDTO.getOutputs()) {
                            outputMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getMappings())) {
                        for (JobComponentInstanceOutMapping it : jobExportDTO.getMappings()) {
                            outMappingMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getRelations())) {
                        for (JobComponentInstanceRelation it : jobExportDTO.getRelations()) {
                            relationMapper.insert(it);
                        }
                    }
                    if (CollUtil.isNotEmpty(jobExportDTO.getSchedulers())) {
                        for (JobComponentInstanceScheduler it : jobExportDTO.getSchedulers()) {
                            schedulerMapper.insert(it);
                        }
                    }
                }
            }
        }
    }

    /**
     * 分页查询应用
     */
    @Override
    public Page<WebPubApp> pageApp(AppPageParam param) {
        int pageNum = param.getPage() == null ? 1 : param.getPage();
        int pageSize = param.getPageSize() == null ? 10 : param.getPageSize();
        Page<WebPubApp> page = new Page<>(pageNum, pageSize);
        String name = "";
        if (StrUtil.isNotBlank(param.getName())) {
            name = "%" + param.getName() + "%";
        }
        Page<WebPubApp> appPage = appMapper.search(page, name);
        if (CollUtil.isNotEmpty(appPage.getRecords())) {
            //查询应用下面的作业
            List<Integer> appIdList = appPage.getRecords().stream().map(WebPubApp::getId).toList();
            List<Integer> devAppIdList = appPage.getRecords().stream().map(WebPubApp::getDevAppId).toList();
            //应用页面信息
            List<WebPubPage> pages = pageMapper.selectList(Wrappers.<WebPubPage>lambdaQuery().in(WebPubPage::getAppId, appIdList));
            Map<Integer, List<WebPubPage>> pageMap = pages.stream().collect(Collectors.groupingBy(WebPubPage::getAppId));
            //应用作业信息
            List<Job> jobs = jobMapper.selectList(Wrappers.<Job>lambdaQuery().in(Job::getAppId, devAppIdList));
            Map<Integer, List<Job>> jobMap = jobs.stream().collect(Collectors.groupingBy(Job::getAppId));
            //应用数据源信息
            List<AppDataSource> dataSourceList = appDataSourceMapper.selectList(Wrappers.<AppDataSource>lambdaQuery().in(AppDataSource::getAppId, devAppIdList));
            Map<Integer, List<AppDataSource>> datasourceMap = dataSourceList.stream().collect(Collectors.groupingBy(AppDataSource::getAppId));
            for (WebPubApp it : appPage.getRecords()) {
                //作业信息
                List<Job> jobList = new ArrayList<>();

                List<WebPubPage> tempPages = pageMap.get(it.getId());
                if (CollUtil.isNotEmpty(tempPages)) {
                    Job job = new Job();
                    job.setName(it.getName() + it.getVersion());
                    job.setType(1);
                    job.setImportTime(it.getImportTime());
                    List<AppDataSource> dsList = datasourceMap.get(it.getDevAppId());
                    if (CollUtil.isNotEmpty(dsList)) {
                        job.setDatasourceId(dsList.get(0).getId());
                    }
                    jobList.add(job);
                }
                List<Job> tempList = jobMap.getOrDefault(it.getDevAppId(), Collections.emptyList());
                for (Job job : tempList) {
                    job.setType(2);
                    job.setImportTime(it.getImportTime());
                }
                jobList.addAll(tempList);
                it.setJobs(jobList);
            }
        }
        return appPage;
    }

    /**
     * 应用下用户组查询
     */
    @Override
    public List<SysUsergroup> userGroupList(Integer appId) {
        LambdaQueryWrapper<SysUsergroup> queryWrapper = Wrappers.<SysUsergroup>lambdaQuery().eq(SysUsergroup::getAppId, appId)
                .eq(SysUsergroup::getDeleteFlag, 0);
        return sysUsergroupMapper.selectList(queryWrapper);
    }

    /**
     * 组成员搜索
     */
    @Override
    public IPage<AppUserDTO> searchAppUser(AppUserSearchParam param, String currentUserId) {
        Page page = null;
        if (param.getPage() != null && param.getPageSize() != null) {
            page = new Page(param.getPage(), param.getPageSize());
        } else {
            page = new Page(1, 100000);
        }
        String name = "";
        if (StrUtil.isNotBlank(param.getName())) {
            name = "%" + param.getName() + "%";
        }
        Page<AppUserDTO> pages = usergroupUserMapper.pageAppUser(page, name, param.getGroupId());
        if (CollUtil.isNotEmpty(pages.getRecords())) {
            //当前用户应用角色
            Integer roleId = userAppRoleMapper.findUserRoleId(param.getGroupId(), currentUserId);
            for (AppUserDTO it : pages.getRecords()) {
                it.setMobileno(DesensitizedUtil.mobilePhone(it.getMobileno()));
                if (roleId != null && it.getRoleId() <= roleId) {
                    it.setEnable(false);
                } else {
                    it.setEnable(true);
                }
            }
        }
        return pages;
    }

    /**
     * 查询授权角色
     */
    @Override
    public List findAuthRoles(Integer appId, String userId) {
        Integer count = userAppRoleMapper.countAppUser(appId, userId);
        if (count <= 0) {
            SysUser sysUser = sysUserMapper.selectById(userId);
            if (Integer.valueOf(1).equals(sysUser.getAdminFlag())) {
                return UcRoleEnum.getManageRoles();
            }
            return Collections.emptyList();
        }
        //查询是否拥有者
        SysBusinessApp app = businessAppMapper.selectOne(Wrappers.<SysBusinessApp>lambdaQuery().eq(SysBusinessApp::getBizCode, String.valueOf(appId)));
        if (userId.equals(app.getOwner())) {
            //应用拥有者
            return UcRoleEnum.getOwnerRole();
        }
        return UcRoleEnum.getManageRoles();
    }

    /**
     * 用户应用授权
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Integer userAppAuth(SysUsergroupUser usergroupUser) {
        //删除旧授权
        LambdaQueryWrapper<SysUsergroupUser> queryWrapper = Wrappers.<SysUsergroupUser>lambdaQuery()
                .eq(SysUsergroupUser::getUserId, usergroupUser.getUserId())
                .eq(SysUsergroupUser::getGroupId, usergroupUser.getGroupId());
        usergroupUserMapper.delete(queryWrapper);
        //如果是拥有者角色
        boolean isChangeOwner = false;
        if (UcRoleEnum.OWNER.code.equals(usergroupUser.getRoleId())) {
            //修改应用拥有者
            SysBusinessApp app = businessAppMapper.selectOne(Wrappers.<SysBusinessApp>lambdaQuery().eq(SysBusinessApp::getBizCode, String.valueOf(usergroupUser.getAppId())));
            String oldOwnerId = app.getOwner();
            app.setOwner(usergroupUser.getUserId());
            businessAppMapper.updateById(app);
            //老拥有者角色去掉
            usergroupUserMapper.delete(Wrappers.<SysUsergroupUser>lambdaQuery().eq(SysUsergroupUser::getRoleId, UcRoleEnum.OWNER.code)
                    .eq(SysUsergroupUser::getAppId, usergroupUser.getAppId()));
            SysUsergroupUser oldUser = new SysUsergroupUser();
            oldUser.setAppId(usergroupUser.getAppId());
            oldUser.setGroupId(usergroupUser.getGroupId());
            oldUser.setUserId(oldOwnerId);
            oldUser.setRoleId(UcRoleEnum.TEST.code);
            usergroupUserMapper.insert(oldUser);
            isChangeOwner = true;
        }
        usergroupUserMapper.insert(usergroupUser);
        if (isChangeOwner) {
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Integer saveAppUser(String groupId, List<SysUsergroupUser> userList, String currentUserId) {
        //删除旧用户
        LambdaQueryWrapper<SysUsergroupUser> queryWrapper = Wrappers.<SysUsergroupUser>lambdaQuery().eq(SysUsergroupUser::getGroupId, groupId);
        usergroupUserMapper.delete(queryWrapper);
        boolean isChangeOwner = false;
        if (CollUtil.isNotEmpty(userList)) {
            //统计拥有者
            long count = userList.stream().filter(it -> UcRoleEnum.OWNER.code.equals(it.getRoleId())).count();
            if (count > 2) {
                throw new WamingException("应用只能设置一个拥有者");
            }
            if (count == 2) {
                isChangeOwner = true;
            }
            for (SysUsergroupUser it : userList) {
                //如果要修改组织管理员，要把当前管理员改成体验者
                if (isChangeOwner && currentUserId.equals(it.getUserId()) && it.getRoleId().equals(UcRoleEnum.OWNER.code)) {
                    it.setRoleId(UcRoleEnum.TEST.code);
                }
                if (UcRoleEnum.OWNER.code.equals(it.getRoleId())) {
                    //修改应用拥有者
                    SysBusinessApp app = businessAppMapper.selectOne(Wrappers.<SysBusinessApp>lambdaQuery().eq(SysBusinessApp::getBizCode, String.valueOf(it.getAppId())));
                    app.setOwner(it.getUserId());
                    businessAppMapper.updateById(app);
                    //老拥有者角色去掉
                    usergroupUserMapper.delete(Wrappers.<SysUsergroupUser>lambdaQuery().eq(SysUsergroupUser::getRoleId, UcRoleEnum.OWNER.code)
                            .eq(SysUsergroupUser::getAppId, it.getAppId()));
                }
                usergroupUserMapper.insert(it);
            }
        }
        if (isChangeOwner) {
            return 1;
        }
        return 0;
    }

    /**
     * 应用拥有者信息
     */
    @Override
    public SimpleUserDTO findAppOwner(Integer appId) {
        SimpleUserDTO appOwner = userAppRoleMapper.findAppOwner(appId);
        if (appOwner == null) {
            return new SimpleUserDTO();
        }
        return appOwner;
    }

    /**
     * 应用下用户查询
     */
    @Override
    public List<SysUser> notInGroupUser(String orgId, String groupId, String userId) {
        if (StrUtil.isBlank(orgId)) {
            SysUsergroup sysUsergroup = sysUsergroupMapper.selectById(groupId);
            orgId = sysUsergroup.getOrgId();
        }
        List<SysUserOrg> orgUsers = sysUserOrgMapper.selectByMap(ImmutableMap.of("org_id", orgId));
        if (!CollectionUtils.isEmpty(orgUsers)) {
            //组内用户查询
            List<String> inIdList = new ArrayList<>();
            //传了组ID则去掉组内的用户
            if (StrUtil.isNotBlank(groupId)) {
                List<SysUsergroupUser> groupUserList = usergroupUserMapper.selectList(Wrappers.<SysUsergroupUser>lambdaQuery()
                        .eq(SysUsergroupUser::getGroupId, groupId));
                for (SysUsergroupUser it : groupUserList) {
                    inIdList.add(it.getUserId());
                }
            }
            List<String> userIds = orgUsers.stream().filter(it -> !inIdList.contains(it.getUserId()))
                    .map(SysUserOrg::getUserId).toList();
            if (CollUtil.isEmpty(userIds)) {
                return Collections.emptyList();
            }
            QueryWrapper<SysUser> userQuery = new QueryWrapper<>();
            userQuery.in("id", userIds);
            return sysUserMapper.selectList(userQuery);
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * 查询应用权限编码
     */
    @Override
    public Map<String, Set<String>> findAppFunctionCode(AppFunctionParam param) {
        if (CollUtil.isEmpty(param.getAppIds())) {
            return new HashMap<>();
        }
        Map<String, Set<String>> resultMap = new HashMap<>();
        SysUser sysUser = sysUserMapper.selectById(param.getUserId());
        if (Integer.valueOf(1).equals(sysUser.getAdminFlag())) {
            Set<String> allCodes = userAppRoleMapper.findAllUcCode();
            for (Integer appId : param.getAppIds()) {
                resultMap.put(String.valueOf(appId), allCodes);
            }
        } else {
            List<AppFunctionDTO> dtoList = userAppRoleMapper.findAppFunctionCode(param.getUserId(), param.getAppIds());
            for (AppFunctionDTO dto : dtoList) {
                Set<String> set = resultMap.getOrDefault(String.valueOf(dto.getAppId()), new HashSet<>());
                set.add(dto.getCode());
                resultMap.put(String.valueOf(dto.getAppId()), set);
            }
        }
        log.info("app function code is {}", JSONObject.toJSONString(resultMap));
        return resultMap;
    }

    /**
     * @param appShare
     * @return
     */
    @Override
    public String saveAppShare(AppShare appShare) {
        String shareKey = UlidCreator.getMonotonicUlid().toString().toLowerCase();
        appShare.setShareKey(shareKey);
        appShare.setCreateTime(new Date());
        appShareMapper.insert(appShare);
        return shareKey;
    }

    /**
     * 查询分享信息
     */
    @Override
    public AppShare findAppShare(String shareKey) {
        return appShareMapper.selectOne(Wrappers.<AppShare>lambdaQuery()
                .eq(AppShare::getShareKey, shareKey));
    }

    /**
     * 我参与的应用ID
     */
    @Override
    public Set<Integer> getMyPartAppId(String userId) {
        return usergroupUserMapper.selectByMap(ImmutableMap.of("user_id", userId))
                .stream().map(SysUsergroupUser::getAppId).collect(Collectors.toSet());
    }

    /**
     * 保存数据源信息
     */
    @Override
    public AppDataSource saveDataSource(AppDataSource appDataSource) {
        if (appDataSource.getId() == null) {
            throw new WamingException("ID参数不能为空");
        }
        //修改
        if (StrUtil.isNotBlank(appDataSource.getPassword())) {
            appDataSource.setPassword(HexUtil.encodeHexStr(appDataSource.getPassword().getBytes()));
        } else {
            appDataSource.setPassword(appDataSourceMapper.selectById(appDataSource.getId()).getPassword());
        }
        appDataSourceMapper.updateById(appDataSource);
        return appDataSource;
    }

    /**
     * 查询应用数据源信息
     */
    @Override
    public AppDataSource findDataSource(Integer id) {
        AppDataSource appDataSource = appDataSourceMapper.selectById(id);
        if (appDataSource != null) {
            //密码回显
            appDataSource.setPassword(HexUtil.decodeHexStr(appDataSource.getPassword(), StandardCharsets.ISO_8859_1));
            DataSourceEnum dataSourceEnum = DataSourceEnum.getByCode(appDataSource.getType());
            appDataSource.setTypeName(dataSourceEnum.desc);
            return appDataSource;
        }
        throw new WamingException("应用未配置数据源");
    }

}
